package com.marketapp.ws;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.marketapp.helper.ServiceException;

@Service
public class EquityDataWSImpl implements IEquityDataWS {

	private Properties properties;

	@Override
	public Map<String, String> getQuoteDetailsByName(String equityId)
			throws ServiceException {

		Map<String, String> equityDetailsMap;
		HttpClient httpClient = new HttpClient();

		String request = properties.getProperty("api.finance") + equityId;

		if (!properties.getProperty("http.setProxy").equals("FALSE")) {
			HostConfiguration hostConfiguration = httpClient
					.getHostConfiguration();
			hostConfiguration.setProxy(
					properties.getProperty("http.proxyHost"),
					Integer.parseInt(properties.getProperty("http.proxyPort")));
		}
		GetMethod getMethod = new GetMethod(request);

		try {
			int statusCode = httpClient.executeMethod(getMethod);
			if (statusCode != HttpStatus.SC_OK) {
				throw new ServiceException(
						"Connection refused: Unable to consume service.");
			} else {
				equityDetailsMap = parseDocument(request);
			}
		} catch (Exception e) {
			throw new ServiceException(
					"Connection refused: Unable to consume service."
							+ e.getMessage());
		}

		return equityDetailsMap;
	}

	@Override
	public Map<String, String> getCurrentQuoteByName(String... equityId) {
		return null;
	}

	public Properties getProperties() {
		return properties;
	}

	public void setProperties(Properties properties) {
		this.properties = properties;
	}

	public Map<String, String> parseDocument(String xmlDocument) {
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();
		Map<String, String> equityDetailsMap = new HashMap<String, String>();

		try {
			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			Document dom = builder.parse(xmlDocument);

			// get the root element
			Element rootElement = dom.getDocumentElement();

			// get required equity details
			String stockElements = properties.getProperty("stockInformation");
			String[] stockElementArr = stockElements.split(",");

			for (String stockElement : stockElementArr) {
				String elementNode = getNode(rootElement, stockElement);
				equityDetailsMap.put(stockElement, elementNode);
			}

			removeCharacter(equityDetailsMap, "+");

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return equityDetailsMap;
	}

	private String getNode(Element rootElement, String nodeName) {
		NodeList nodeList = rootElement.getElementsByTagName(nodeName);
		String last = "";
		if (nodeList != null && nodeList.getLength() > 0) {
			Element lastElement = (Element) nodeList.item(0);
			last = lastElement.getAttribute("data");
		}
		return last;
	}

	private Map<String, String> removeCharacter(Map<String, String> detailMap,
			String character) {
		for (Entry<String, String> entry : detailMap.entrySet()) {
			if (entry.getKey().equals("change")) {
				String detailValue = entry.getValue();
				if (detailValue.contains(character)) {
					detailValue = detailValue.substring(1);
				}
				entry.setValue(detailValue);
			}
		}
		return detailMap;
	}
}
